package com.pervasive.geoTagging;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;


import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.Camera.*;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;


public class CustomCameraActivity extends Activity implements SurfaceHolder.Callback {
    
    private SensorManager sensorManager;
    private Camera camera;
    private Button b;
    private boolean sdk;
    private float[] orientation = new float[3];
    private String location, flash, sDate;
    private int quality;
    private Bitmap bmp;
    private File file;
    private SensorEventListener sensorEventListener = new SensorEventListener() {
        public void onAccuracyChanged(Sensor sensor, int accuracy) { }
        /* Get the Sensors */
        public void onSensorChanged(SensorEvent event) {
        	if (event.sensor.getType()==Sensor.TYPE_ORIENTATION)
        		System.arraycopy(event.values, 0, orientation, 0, 3);
        }
    };
    
    private class MyListener implements OnClickListener{  
    	public void onClick(View v) {
    		AutoFocusCallback autoCallback = new AutoFocusCallback() {
    			public void onAutoFocus(boolean success, Camera cm) {
    				PictureCallback jpegCallback = new PictureCallback() {
    					public void onPictureTaken(byte[] data, Camera camera) {
    						int freeNumber = 1;
                            if(MainActivity.pref.contains("freeNumber"))
                            	freeNumber = MainActivity.pref.getInt("freeNumber", 1);
                            String path = MainActivity.DIR_OFF.getAbsolutePath()+"/"+freeNumber+"perv.jpeg";
                            try {
                            	bmp = BitmapFactory.decodeByteArray(data,0,data.length);
                                Log.i("Orientation", "orientation :"+orientation[0]+", "+orientation[1]+", "+orientation[2]);
                                Matrix mtx = new Matrix();
                                if(orientation[1] > -25 && orientation[1]< 25){
                                	if(orientation[2]<-25)
                                		mtx.postRotate(180);
                                	else if(orientation[2]>25)
                                		mtx.postRotate(0);
                                }else{
                                	mtx.postRotate(90);
                                }
                                bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mtx, true);
                                file = new File (path);
                                if(!file.exists())
                                	file.createNewFile();
                                FileOutputStream fileOutputStream = new FileOutputStream(file);                                
                                BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
                                bmp.compress(CompressFormat.JPEG, quality, bos);
                                
                                bos.flush();
                                bos.close();
                            } catch (IOException e) {
                            	Log.d("CAMERA", e.getMessage());
                            }
                            try {
                            	location = MappaActivity.getCurrentLocation();
                            	if(location==null)
                            		location = "Benevento, Italia";
                            } catch (/*IO*/Exception e) {
                            	location = "Benevento, Italia";
                            }
                            
                            b.setEnabled(true);
                            SimpleDateFormat form = (SimpleDateFormat) SimpleDateFormat.getDateTimeInstance();
                            sDate = form.format(new Date());
                            Intent i = new Intent(getApplicationContext(), SaveActivity.class);
                            i.putExtra("uri", path);
                            startActivityForResult(i,1);
    					}
    				};
                    camera.takePicture(null, null, jpegCallback);
                    
    			}
    		};
    		camera.autoFocus(autoCallback);
            b.setEnabled(false);
    	}
    }

    

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.portrait);
        sdk = Integer.parseInt(Build.VERSION.SDK) >= 8;
        sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
        b = (Button)findViewById(R.id.button);
        b.setOnClickListener(new MyListener());
        SurfaceView surface = (SurfaceView)findViewById(R.id.surface);
        SurfaceHolder holder = surface.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        holder.setFixedSize(400, 300);
    }

    protected void onResume() {
        super.onResume();
        flash = MainActivity.pref.getString("Flash", "Auto");
        String q = MainActivity.pref.getString("Quality", "Media");
        if (q.equalsIgnoreCase("Bassa"))
            quality = 20;
        else if (q.equalsIgnoreCase("Media"))
        	quality = 50;
        else if (q.equalsIgnoreCase("Alta"))
        	quality = 100;
        sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(sensorEventListener);
    }
    
    public void surfaceCreated(SurfaceHolder holder) {
    	
    	try{
                camera = Camera.open();
        }catch (Exception e) {}
        
        Parameters p = camera.getParameters();
        if (sdk)
            setDisplayOrientation(camera, 90);
        else{   
                p.set("orientation", "portrait");
                p.set("rotation", 90);
        }
        
        if (flash.equalsIgnoreCase("Auto"))
                p.setFlashMode(Parameters.FLASH_MODE_AUTO);
        else if (flash.equalsIgnoreCase("Off"))
                p.setFlashMode(Parameters.FLASH_MODE_OFF);
        else if (flash.equalsIgnoreCase("On"))
                p.setFlashMode(Parameters.FLASH_MODE_ON);
        else if (flash.equalsIgnoreCase("Red"))
                p.setFlashMode(Parameters.FLASH_MODE_RED_EYE);
        
        p.setJpegQuality(quality);
        
        camera.setParameters(p);
        
        try {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
        } catch (IOException e) {
                Log.d("CAMERA", e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        try{
                camera.stopPreview();
                camera.release();
        }catch (Exception e) {
                        // TODO: handle exception
                }
    }

    protected void onDestroy() {
        super.onDestroy();
        try{
            camera.stopPreview();
            camera.release();
        }catch (Exception e) {}
    }
         
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { }
        
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	if(requestCode == 1){
    		if(resultCode == Activity.RESULT_OK){

    			String note = data.getExtras().getString("Note");
    			int id = MainActivity.pref.getInt("freeNumber", 1);
    	        MappaActivity.addLocation(location);
    	        
    	        MainActivity.pref.edit().putInt("freeNumber", id+1).commit();
    	        File noteFile = new File(MainActivity.DIR_OFF.getAbsolutePath()+"/"+id+"perv.txt");
    	        if(!noteFile.exists())
    			try {
    				noteFile.createNewFile();
    			} catch (IOException e2) {
    				Toast.makeText(getApplicationContext(), "Errore", Toast.LENGTH_SHORT).show();
    			}
    	        try {
    				PrintStream out = new PrintStream(new FileOutputStream(noteFile));
    				out.println(location);
    				out.println(sDate);
    				out.println(note);
    			}
    			catch (IOException e1) {}
    			Log.i("CustomCamera", "Salvato");
    			String ip = MainActivity.pref.getString("IP", "localhost");
    			if(!ip.equalsIgnoreCase("localhost")){
    	            Intent serviceIntent = new Intent(CustomCameraActivity.this, UploadService.class);
    	            startService(serviceIntent);
    			}
    		}else{
                file.delete();
            }
    	}
    }
        
        
    protected void setDisplayOrientation(Camera camera, int angle){
    	Method downPolymorphic;
    	try{
    		downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
            if (downPolymorphic != null)
            	downPolymorphic.invoke(camera, new Object[] { angle });
        }
        catch (Exception e){}
    } 
}